<!--
    三元表达式
        左表达式 操作符 右表达式
    左表达式：
        可选类型原子和表达式，选择不同对 操作符产生以下影响：
            1.原子，操作符按照原子配置范围选定（配置时只能有比较操作符），
            2.表达式，操作符只能选择比较操作符（二级表达式只能进行算数运算）
    操作符：
        根据 左表达式和右表达式进行动态变更（包含，比较操作符，算数运算符）
    右表达式：
        可选类型原子、表达式和输入值，选择不同对 操作符产生以下影响：
            1.原子，操作符只能选择比较操作符，
            2.表达式，操作符只能选择比较操作符（二级表达式只能进行算数运算）
            3.输入值，操作符按照原子配置范围选定（配置时只能有比较操作符）

   左右表达式关系：
        左表达式类型决定右表达式类型；
            原子->原子，表达式，输入值
            表达式->表达式，原子，只出文本输入值

-->
<style>
    .rule-express-error{
       border-bottom: #f60854 solid 1px;
    }
    .rule-transfer{
        top: 0;
    }
    .rule-drop-down{
        max-height: 235px;
        height: 235px;
    }
</style>
<template>
    <div :class="className">
        <div style="float: left;font-size: 12px">
            <span v-show="showLabel">{{label}}</span>
            {{not?' 非':' '}}
            (
        </div>
        <div style="float: left">
            <div style="float: left">
                <div v-if="leftType=='express'" style="float: left;margin-left: 5px">
                    <express-type location="left" @validateExpress="validateExpress" @calexp="handle" :onlyArithmetic="true" :ruleAtoms="ruleAtoms" :express="this.express.left.express" :operations="operations"/>
                </div>
                <Dropdown :transfer="true" class='rule-tree-dropdown' transferClassName="rule-transfer" ref="leftExp" trigger="click" @on-click="leftTypeSelect">
                    <a href="javascript:void(0)" style="color: #fa8c16">
                        {{leftType==''?'左表达式':(leftType=='atom'?leftAtomName:'')}}
                        <Tooltip content="选择左表达式类型" placement="top">
                            <Icon type="ios-arrow-down"  v-on:click.stop="handlerTypeChangeClick('leftExp')" size="12"/>
                        </Tooltip>
                    </a>
                    <DropdownMenu slot="list" >
                        <Dropdown :transfer="true" placement="right-start" transferClassName="rule-transfer rule-drop-down" :pageIndexChangeCallBack="leftPageChange" :page-data="leftAtomPageInfo">
                            <DropdownItem>
                                原子
                                <Icon type="ios-arrow-forward"></Icon>
                            </DropdownItem>
                            <div slot="search">
                                <Input search enter-button placeholder="输入原子名" style="width: auto" @on-search="leftSearch"/>
                            </div>
                            <DropdownMenu slot="list">
                                <DropdownItem :key="item.key"  v-for="item in leftAtomToSelect" :name="'atom_'+item.key">{{ item.name }}</DropdownItem>
                            </DropdownMenu>
                        </Dropdown>
                        <DropdownItem name="express">表达式</DropdownItem>
                    </DropdownMenu>
                </Dropdown>
            </div>
            <div  style="float: left;margin-left: 5px;">
                <Dropdown :transfer="true" class='rule-tree-dropdown'  transferClassName="rule-transfer" trigger="click" @on-click="operationSelected">
                    <a href="javascript:void(0)" style="color: #c803ff">
                        {{this.operationName}}
                        <Tooltip content="选择操作符类型" placement="top">
                            <Icon type="ios-arrow-down" size="12"/>
                        </Tooltip>
                    </a>
                    <DropdownMenu slot="list" v-if="operationsSelect.length>0">
                        <DropdownItem :key="item.key"  v-for="item in operationsSelect" :name="item.key">{{ item.name }}</DropdownItem>
                    </DropdownMenu>
                </Dropdown>
            </div>
            <div style="float: left">
                <div v-if="rightType=='value'" style="float: left;margin-left: 5px;padding-left: 5px">
                    <InType  ref="inType" @calexp="handle" v-if="operation==='in'" :atomKey="leftAtom" :inputType="inputType" :inputConfig="inputConfig" :valueNames="valueNames" :values="values"/>
                    <CommonType @calexp="handle" v-else :atomKey="leftAtom" :inputType="inputType" :inputConfig="inputConfig" :valueIndex="0" :valueNames="valueNames" :values="values"/>
                </div>
                <div v-if="rightType=='express'" style="float: left;margin-left: 5px">
                    <express-type location="right" @validateExpress="validateExpress" @calexp="handle" :onlyArithmetic="true" :ruleAtoms="ruleAtoms" :express="this.express.right.express" :operations="operations"/>
                </div>
                <Dropdown :transfer="true" class='rule-tree-dropdown' transferClassName="rule-transfer" trigger="click" ref="rightExp" @on-click="rightTypeSelect">
                    <a href="javascript:void(0)" style="color: #026ff1">
                        {{rightType==''?'右表达式':(rightType=='atom'?rightAtomName:'')}}
                        <Tooltip content="选择右表达式类型" placement="top">
                            <Icon type="ios-arrow-down" v-on:click.stop="handlerTypeChangeClick('rightExp')" size="12"/>
                        </Tooltip>
                    </a>
                    <DropdownMenu slot="list" >
                        <DropdownItem name="value">输入值</DropdownItem>
                        <Dropdown :transfer="true"   placement="right-start" transferClassName="rule-transfer rule-drop-down" :pageIndexChangeCallBack="rightPageChange" :page-data="rightAtomPageInfo">
                            <DropdownItem>
                                原子
                                <Icon type="ios-arrow-forward"></Icon>
                            </DropdownItem>
                            <div slot="search">
                                <Input search enter-button placeholder="输入原子名" style="width: auto" @on-search="rightSearch"/>
                            </div>
                            <DropdownMenu slot="list">
                                <DropdownItem  :key="item.key" v-for="item in rightAtomToSelect" :name="'atom_'+item.key">{{ item.name }}</DropdownItem>
                            </DropdownMenu>
                        </Dropdown>
                        <DropdownItem  name="express">表达式</DropdownItem>
                    </DropdownMenu>
                </Dropdown>
            </div>
        </div>
        <div style="float: left;margin-left: 5px;">)</div>
        <div style="clear:both"></div>
    </div>
</template>
<style lang="less" scoped>
</style>
<script>
    import ruiMixin from "_c/rui-auto/rui-rules/src/mixin/rule-mixin";
    import InType from "_c/rui-auto/rui-rules/src/component/express/InType";
    import CommonType from "_c/rui-auto/rui-rules/src/component/express/CommonType"
    import {
        genTernaryExpression,
        genOperator,
        genRight,
    } from '_c/rui-auto/rui-rules/src/component/util/index'
    export default {
        name: 'express-type',
        mixins: [ruiMixin],
        components:{
            'InType':InType,
            'CommonType':CommonType
        },
        props: {
            express: {
                type: Object
            },
            depth:{
                type:Number,
                require: true
            },
            ruleAtoms: {
                type: Array,
                require:true
            },
            operations: {
                type: Array,
                require:true
            },
            onlyArithmetic:{
                type:Boolean,
                default:()=>{
                    return false;
                }
            },
            label:{
                type:String,
                default:()=>{
                    return '';
                }
            },
            not:{
                type:Boolean,
                default:()=>{
                    return false;
                }
            },
            index:{
                type:Number,
                default:()=>{
                    return 1;
                }
            },
            showLabel:{
                type:Boolean,
                default:()=>{
                    return false;
                }
            },
            location:{
                type:String,
                default:()=>{
                    return ''
                }
            },
            readOnly:{
                type:Boolean,
                default(){
                    return false;
                }
            }
        },
        data() {
            return {
                leftAtom:'',
                leftAtomName:'选择原子',
                rightAtom:'',
                leftCheck:true,
                rightAtomName:'选择原子',
                operation:'',
                operationName:'选择操作符',
                inputType:'text',
                inputConfig:{},
                atomsToSelect:[],
                operationsSelect:[],
                values:[],
                valueNames:[],
                leftType:'',
                operatorType:'',
                operatorCheck:true,
                rightType:'',
                rightCheck:true,
                init:false,
                leftAtomPageInfo:{
                    pageSize:5,
                    pageIndex:1,
                    enable:true,
                    total:100,
                    searchCondition:''
                },
                rightAtomPageInfo:{
                    pageSize:5,
                    pageIndex:1,
                    enable:true,
                    total:100,
                    searchCondition:''
                }
            }
        },
        mounted() {
            if(!this.express){
                return;
            }
            this.leftType = this.express.left.type;
            if(this.leftType=='atom'){
                this.leftAtom = this.express.left.atom.key;
                this.leftAtomName = this.express.left.atom.name;
            }
            this.rightType = this.express.right.type;
            if(this.rightType=='atom') {
                this.rightAtom = this.express.right.atom.key;
                this.rightAtomName = this.express.right.atom.name;
            }
            if(this.leftType=='atom'){
                this.inputType = this.express.left.atom.component;
                this.inputConfig = this.express.left.atom.componentConfig;
            }
            if(this.express.right.valueNames!=''){
                this.valueNames.push(...this.express.right.valueNames.split(','));
            }
            if(this.express.right.value!=''&&this.inputType!='cascader'){
                if(this.inputType!='number'){
                    this.values.push(...this.express.right.value.split(','));
                }else{
                    this.express.right.value.split(',').forEach(str=>{
                        this.values.push(parseFloat(str));
                    });
                }
            }else if(this.express.right.value!=''&&this.inputType=='cascader'){
                let temp = this.express.right.value.split(',');
                temp.forEach(value => {
                    this.values.push(value.split(';;;'));
                });
            }

            this.operation = this.express.operator.key;
            this.operatorType = this.express.operator.value;
            this.operationName = this.express.operator.name==''?'选择操作符':this.express.operator.name;

            if(this.leftType==='atom'){
                let selectAtom,self = this;
                this.ruleAtoms.forEach(atom=>{
                    if(atom.key === self.leftAtom){
                        selectAtom = self.clone(atom)
                    }
                })
                if(!this.onlyArithmetic&&selectAtom) {
                    if (selectAtom.operatorScope === 'all') {
                        this.operationsSelect=this.clone(this.operations)
                    } else if (selectAtom.operatorScope === 'cust' && selectAtom.operatorTypes.length) {
                        this.operationsSelect.splice(0,this.operationsSelect.length);
                        this.operations.forEach(operation => {
                            selectAtom.operatorTypes.forEach(type => {
                                if (type === operation.key) {
                                    self.operationsSelect.push(operation)
                                }
                            })
                        })
                    }
                }else if(this.onlyArithmetic){
                    this.operationsSelect.splice(0,this.operationsSelect.length);
                    self.operationsSelect.push(...this.clone(this.arithmeticOperator));
                }
            }
            this.$nextTick(()=>{
                this.init = true;
            })

            if(this.onlyArithmetic){
                this.atomsToSelect.push(...this.ruleAtoms.filter(atom=>{
                    return atom.component === 'number'
                }))
            }else{
                this.atomsToSelect.push(...this.ruleAtoms)
            }
            this.leftAtomPageInfo.total = this.atomsToSelect.length;
            this.rightAtomPageInfo.total = this.atomsToSelect.length;

        },
        computed: {
            className(){
                this.checkExpressValidate();
                if(this.onlyArithmetic){
                    return 'expressWidthCal';
                }
                return (this.rightCheck&&this.leftCheck&&this.operatorCheck)?'expressWidthCal':'expressWidthCal rule-express-error';
            },
            rightAtomToSelect(){
                let self = this;
                if(this.rightAtomPageInfo.searchCondition!==''){
                    let filtersResult = [];
                    this.atomsToSelect.forEach(item=>{
                        if(item.name.indexOf(self.rightAtomPageInfo.searchCondition)>-1){
                            filtersResult.push(item);
                        }
                    })
                    this.rightAtomPageInfo.total = filtersResult.length
                    if (filtersResult.length > this.rightAtomPageInfo.pageSize) {
                        let indexStart = (this.rightAtomPageInfo.pageIndex - 1) * this.rightAtomPageInfo.pageSize;
                        let indexEnd = (this.rightAtomPageInfo.pageIndex) * this.rightAtomPageInfo.pageSize;
                        return filtersResult.slice(indexStart, indexEnd)
                    } else {
                        return filtersResult;
                    }
                }else {
                    this.rightAtomPageInfo.total = this.atomsToSelect.length
                    if (this.atomsToSelect.length > this.rightAtomPageInfo.pageSize) {
                        let indexStart = (this.rightAtomPageInfo.pageIndex - 1) * this.rightAtomPageInfo.pageSize;
                        let indexEnd = (this.rightAtomPageInfo.pageIndex) * this.rightAtomPageInfo.pageSize;
                        return this.atomsToSelect.slice(indexStart, indexEnd)
                    } else {
                        return this.atomsToSelect;
                    }
                }
            },
            leftAtomToSelect(){
                let self = this;
                if(this.leftAtomPageInfo.searchCondition!==''){
                    let filtersResult = [];
                    this.atomsToSelect.forEach(item=>{
                        if(item.name.indexOf(self.leftAtomPageInfo.searchCondition)>-1){
                            filtersResult.push(item);
                        }
                    })
                    this.leftAtomPageInfo.total = filtersResult.length
                    if (filtersResult.length > this.leftAtomPageInfo.pageSize) {
                        let indexStart = (this.leftAtomPageInfo.pageIndex - 1) * this.leftAtomPageInfo.pageSize;
                        let indexEnd = (this.leftAtomPageInfo.pageIndex) * this.leftAtomPageInfo.pageSize;
                        return filtersResult.slice(indexStart, indexEnd)
                    } else {
                        return filtersResult;
                    }
                }else {
                    this.leftAtomPageInfo.total = this.atomsToSelect.length
                    if (this.atomsToSelect.length > this.leftAtomPageInfo.pageSize) {
                        let indexStart = (this.leftAtomPageInfo.pageIndex - 1) * this.leftAtomPageInfo.pageSize;
                        let indexEnd = (this.leftAtomPageInfo.pageIndex) * this.leftAtomPageInfo.pageSize;
                        return this.atomsToSelect.slice(indexStart, indexEnd)
                    } else {
                        return this.atomsToSelect;
                    }
                }
            }
        },
        methods:{
            handle() {
                this.$emit('calexp');
            },
            handlerTypeChangeClick(refKey){
                if(this.$refs[refKey]) {
                    this.$refs[refKey].handleClick()
                }
            },
            leftPageChange(pageIndex){
                this.leftAtomPageInfo.pageIndex=pageIndex;
            },
            rightPageChange(pageIndex){
                this.rightAtomPageInfo.pageIndex=pageIndex;
            },
            validateExpress(location,validate){
                if(location=='left'){
                    this.leftCheck = validate;
                }
                if(location == 'right'){
                    this.rightCheck = validate;
                }
                this.$emit('validate',this.rightCheck&&this.leftCheck&&this.operatorCheck);
            },
            checkExpressValidate(){
                if (this.operation==''){
                    this.operatorCheck = false;
                }else{
                    this.operatorCheck = true;
                }
                if(this.leftType==''||(this.leftType=='atom'&&this.leftAtom=='')){
                    this.leftCheck = false;
                }else if(this.leftType!='express'){
                    this.leftCheck = true;
                }
                if(this.rightType==''||(this.rightType=='atom'&&this.rightAtom=='')||(this.rightType=='value'&&this.values.join('')=='')){
                    this.rightCheck = false;
                }else if(this.rightType!='express'){
                    this.rightCheck = true;
                }
                if(this.$refs['inType']&&!this.$refs['inType'].validate){
                    this.rightCheck = false;
                }
                this.$emit('validate',this.rightCheck&&this.leftCheck&&this.operatorCheck);
                this.$emit('validateExpress',this.location,this.rightCheck&&this.leftCheck&&this.operatorCheck);
            },
            leftTypeSelect(name){
                if((name==='express'&&this.leftType=='express')){
                    return;
                }
                if(name==='express'){
                    this.leftType = 'express';
                    this.leftAtom='';
                    this.inputType='text';
                    this.inputConfig={};
                    this.express.left.type="express";
                    // this.express.left.atom= {};
                    delete this.express.left.atom;
                    this.express.left.express =  genTernaryExpression();
                    if(this.express.right.type=='value') {
                        this.express.right.type = '';
                        this.express.right.value = '';
                        this.values=[];
                        this.valueNames=[];
                        this.express.right.valueNames = '';
                        this.rightType='';
                        this.operation='';
                        this.operationName='选择操作符';
                        this.express.operator.key='';
                        this.express.operator.name='';
                        this.express.operator.value='';
                        this.express.operator.type='';
                    }
                }else if(name.indexOf("atom_")>-1){
                    this.leftType='atom';
                    this.leftAtomSelected(name.replace("atom_",''));
                    // this.express.left.express={}
                    delete this.express.left.express;
                }else{
                    this.leftType='';
                    this.express.left.type="";
                    // this.express.left.atom= {};
                    delete this.express.left.atom;
                    delete this.express.left.express;
                    // this.express.left.express=genTernaryExpression()
                }
                this.handle()
            },
            leftAtomSelected(name){
                let selectAtom,self = this;
                this.ruleAtoms.forEach(atom=>{
                    if(atom.key == name){
                        selectAtom = self.clone(atom)
                    }
                })
                if(!this.onlyArithmetic) {
                    if (selectAtom.operatorScope === 'all') {
                        this.operationsSelect=this.clone(this.operations)
                    } else if (selectAtom.operatorScope === 'cust' && selectAtom.operatorTypes.length) {
                        this.operationsSelect = [];
                        this.operations.forEach(operation => {
                            selectAtom.operatorTypes.forEach(type => {
                                if (type === operation.key) {
                                    self.operationsSelect.push(operation)
                                }
                            })
                        })
                    }
                }else{
                    self.operationsSelect=this.clone(this.arithmeticOperator);
                }
                this.leftAtom= name;
                this.leftAtomName = selectAtom.name;
                this.operationName = '选择操作符';
                this.operation = '';
                this.operatorType='fromAtom';
                this.inputType = selectAtom.component;
                this.inputConfig = selectAtom.componentConfig
                this.express.left.type="atom";
                this.express.left.atom=selectAtom;
                this.express.operator = genOperator()
                this.express.operator.type='fromAtom'
                this.express.right = genRight()
                this.rightType = '';
                this.rightAtom='';
                this.rightAtomName = '';
                this.handle()
            },
            operationSelected(name){
                if(name==this.operation){
                    return;
                }
                this.operationsSelect.forEach(item=>{
                    if(name==item.key){
                        this.operation = item.key;
                        this.operationName = item.name;
                        this.express.operator.key=item.key;
                        this.express.operator.name=item.name;
                        this.express.operator.value=item.value;
                    }
                })
                this.handle()
                this.values.splice(0,this.values.length===1?1:(this.values.length-1));
                this.valueNames.splice(0,this.valueNames.length===1?1:(this.valueNames.length-1));
            },
            rightTypeSelect(name){
                if((name==='express'&&this.rightType=='express')){
                    return;
                }
                if(name==='express'){
                    if(this.operation==='in'){
                        this.$Message.error("操作符为[in]时右表达式只能选择输入值");
                        return
                    }
                    this.rightType = name;
                    this.express.right.type="express";
                    // this.express.right.atom= {};
                    delete this.express.right.atom;
                    this.express.right.value="";
                    this.express.right.express =  genTernaryExpression();
                }else if(name.indexOf("atom_")>-1){
                    this.rightType='atom';
                    if(this.operation==='in'){
                        this.$Message.error("操作符为[in]时右表达式只能选择输入值");
                        return
                    }
                    // this.express.right.express =  genTernaryExpression();
                    delete this.express.right.express;
                    this.express.right.value="";
                    this.rightAtomSelect(name.replace("atom_",''));
                    // this.express.right.express={}
                    delete this.express.right.express;
                }else if(name==='value'){
                    this.rightType = name;
                    // this.express.right.atom= {};
                    delete this.express.right.atom;
                    this.express.right.type="value";
                    this.express.right.value="";
                    // this.express.right.express =  genTernaryExpression();
                    delete this.express.right.express;
                }else{
                    this.rightType='';
                    // this.express.right.atom= {};

                    delete this.express.right.atom;
                    this.express.right.type="";
                    this.express.right.value="";
                    // this.express.right.express=genTernaryExpression()
                    delete this.express.right.express;
                }
                this.handle()
            },
            rightAtomSelect(name){
                let selectAtom,self = this;
                this.ruleAtoms.forEach(atom=>{
                    if(atom.key == name){
                        selectAtom = self.clone(atom)
                    }
                })
                this.rightAtom= name;
                this.rightAtomName = selectAtom.name;
                this.express.right.type="atom";
                this.express.right.atom=selectAtom;
                this.handle()
            },
            leftSearch(value){
                this.leftAtomPageInfo.searchCondition = value;
                this.leftAtomPageInfo.pageIndex = 1;
            },
            rightSearch(value){
                this.rightAtomPageInfo.searchCondition = value;
                this.rightAtomPageInfo.pageIndex = 1;
            },
            typeChange(){
                if(!this.init){
                    return;
                }
                if(this.onlyArithmetic) {
                    this.operationsSelect = this.clone(this.arithmeticOperator);
                    return;
                }
                //左右类型都为空则不处理
                if(this.leftType==''&&this.rightType==''){
                    return;
                }
                // 做类型非atom 和value 操作符是所有比较类型
                if(!(this.leftType=='atom'&&this.rightType=='value')&&this.rightType!=''){
                    if(this.operatorType=='compare'&&this.express.operator.type=='compare'){
                        return;
                    }else{
                        this.operationsSelect = this.clone(this.compareOperator);
                        if(this.express.operator.type!='compare') {
                            this.operatorType = 'compare';
                            this.operationName = '选择操作符';
                            this.express.operator = genOperator()
                            this.express.operator.type = 'compare'
                            this.operation = '';
                        }
                    }
                }else{
                    if(this.operatorType=='fromAtom'&&this.express.operator.type=='fromAtom'){
                        return;
                    }else{
                        if(this.leftAtom!=''){
                            let selectAtom,self = this;
                            this.ruleAtoms.forEach(atom=>{
                                if(atom.key == self.leftAtom){
                                    selectAtom = self.clone(atom)
                                }
                            })
                            if(selectAtom.operatorScope==='all'){
                                this.operationsSelect = this.clone(this.operations)
                            }else if(selectAtom.operatorScope==='cust'&&selectAtom.operatorTypes.length){
                                this.operationsSelect = [];
                                this.operations.forEach(operation=>{
                                    selectAtom.operatorTypes.forEach(type=>{
                                        if(type===operation.key){
                                            self.operationsSelect.push(operation)
                                        }
                                    })
                                })
                            }
                            if(this.express.operator.type!='fromAtom') {
                                this.operationName = '选择操作符';
                                this.operation = '';
                                this.operatorType = 'fromAtom';
                                this.express.operator = genOperator()
                                this.express.operator.type = 'fromAtom'
                                this.inputType = selectAtom.component;
                                this.inputConfig = selectAtom.componentConfig
                            }
                        }
                    }
                }
                this.handle()
            }
        },
        watch:{
            values(){
                if(this.express.right.type=='value'){
                    if(
                        this.inputType==='dic'
                        ||this.inputType==='cascader'
                        ||this.inputType==='custDic'
                        ||this.inputType==='component'
                    ) {
                        this.express.right.valueNames = this.valueNames.join(',')
                    }
                    if(this.inputType=='cascader') {
                        let temp = [];
                        this.values.forEach(value => {
                            temp.push(value.join(';;;'));
                        })
                        this.express.right.value = temp.join(',');
                    }else{
                        this.express.right.value = this.values.join(',');
                    }
                }
                this.handle()
            },
            leftType(){
                this.typeChange();
            },
            rightType(){
                this.typeChange();
            },
        }
    }
</script>
